package com.xbongbong.pay.platform.unionpay.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.pay.enums.PayErrorEnum;
import com.xbongbong.pay.exception.PayApiException;
import com.xbongbong.pay.platform.unionpay.config.UnionPayMeta;
import com.xbongbong.pay.platform.unionpay.config.UnionPayMetaContainer;
import com.xbongbong.pay.platform.unionpay.enums.UnionPayServerEnum;
import com.xbongbong.pay.platform.unionpay.enums.UnionPayUrlEnum;
import com.xbongbong.pay.platform.unionpay.pojo.request.UnionPayBackTransRequest;
import com.xbongbong.pay.platform.unionpay.pojo.request.UnionPayFrontTransRequest;
import com.xbongbong.pay.utils.PayHttpUtil;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 银联api
 * @author 魏荣杰
 * @date 2021/1/19 16:26
 * @since
 * @version
 */
@Service("unionPayApi")
public class UnionPayApi {
    private static final Logger LOG = LoggerFactory.getLogger(UnionPayApi.class);

    @Resource
    private UnionPayMetaContainer unionPayMetaContainer;

    /**
     * Description: 消费接口
     * @param request
     * @param mchId 商户id
     * @return com.xbongbong.pay.platform.unionpay.pojo.response.UnionPayFrontTransSyncResponse
     * @throws
     * @author 魏荣杰
     * @date 2021/1/20 14:56
     * @since
     */
    public CloseableHttpResponse frontTransSync(UnionPayFrontTransRequest request, String mchId) throws PayApiException {
        try {
            UnionPayMeta unionPayMeta = unionPayMetaContainer.getUnionPayMeta(mchId);
            PrivateKey privateKey = UnionPayCertUtil.getSignCertPrivateKey(unionPayMeta.getKeyStore(), unionPayMeta.getConfig().getSignCertPwd());
            request.setCertId(unionPayMeta.getSerialNumber());
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(request));
            Map<String, String> params = new HashMap<>();
            jsonObject.forEach((k, v) -> params.put(k, v.toString()));
            String sign = UnionPaySignUtil.createSign(params, StandardCharsets.UTF_8.toString(), privateKey);
            request.setSignature(sign);
            String url = UnionPayUrlEnum.getUrl(UnionPayServerEnum.TEST, UnionPayUrlEnum.FRONT_TRANS);

            LOG.error("=======  request = " + JSON.toJSONString(request));
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/x-www-form-urlencoded");

            List<NameValuePair> nameValuePairs = new ArrayList<>();
            JSONObject parseObject = JSON.parseObject(JSON.toJSONString(request));
            parseObject.forEach((k, v) -> {
                nameValuePairs.add(new BasicNameValuePair(k, v.toString()));
            });
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairs);
            CloseableHttpResponse response = PayHttpUtil.doPost(HttpClients.createDefault(), url, urlEncodedFormEntity, headers);
            return response;
        } catch (PayApiException e) {
            throw e;
        } catch (Exception e) {
            throw new PayApiException(PayErrorEnum.API_ERROR.getCode(), PayErrorEnum.API_ERROR.getMsg());
        }
    }


    /**
     * Description: 消费撤销接口  退货接口
     * @param request
     * @return com.xbongbong.pay.platform.unionpay.pojo.response.UnionPayBackTransSyncResponse
     * @throws
     * @author 魏荣杰
     * @date 2021/1/20 15:18
     * @since
     */
    public CloseableHttpResponse backTransSync(UnionPayBackTransRequest request, String mchId) throws PayApiException {
        try {
            UnionPayMeta unionPayMeta = unionPayMetaContainer.getUnionPayMeta(mchId);
            PrivateKey privateKey = UnionPayCertUtil.getSignCertPrivateKey(unionPayMeta.getKeyStore(), unionPayMeta.getConfig().getSignCertPwd());
            request.setCertId(unionPayMeta.getSerialNumber());
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(request));
            Map<String, String> params = new HashMap<>();
            jsonObject.forEach((k, v) -> params.put(k, v.toString()));
            String sign = UnionPaySignUtil.createSign(params, StandardCharsets.UTF_8.toString(), privateKey);
            request.setSignature(sign);
            String url = UnionPayUrlEnum.getUrl(UnionPayServerEnum.PRODUCT, UnionPayUrlEnum.BACK_TRANS);

            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/x-www-form-urlencoded");
            List<NameValuePair> nameValuePairs = new ArrayList<>();
            JSONObject parseObject = JSON.parseObject(JSON.toJSONString(request));
            parseObject.forEach((k, v) -> {
                nameValuePairs.add(new BasicNameValuePair(k, v.toString()));
            });
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairs);
            CloseableHttpResponse response = PayHttpUtil.doPost(HttpClients.createDefault(), url, urlEncodedFormEntity, headers);
            return response;
        } catch (PayApiException e) {
            throw e;
        } catch (Exception e) {
            throw new PayApiException(PayErrorEnum.API_ERROR.getCode(), PayErrorEnum.API_ERROR.getMsg());
        }
    }

}
